<?php

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Database\Eloquent\SoftDeletes;

class memberModel extends Model
{
    use SoftDeletes;

    protected $table = 'member';
    protected $primaryKey = 'id';
    protected $appends = ['nickname_hide', 'level_info'];

    public function getNicknameHideAttribute()
    {
        if (!empty($this->nickname)) {
            if (mb_strlen($this->nickname) > 2) {
                $nickname = mb_substr($this->nickname, 0, 2) . '***';
            } else {
                $nickname = $this->nickname;
            }
            return $nickname;
        }
        return null;
    }

    protected function serializeDate($date)
    {
        return $date->format('Y-m-d H:i:s');
    }

    public function getLevelInfoAttribute()
    {
        return !empty($this->attributes['level']) ? agentlevelModel::where('level', $this->attributes['level'])->first() : [];
    }

    public function getParentAttribute()
    {
        return $this->attributes['parent_member_id'] > 0 ? $this->find($this->attributes['parent_member_id']) : [];
    }

    public function gudong()
    {
        return $this->hasOne(gudongModel::class, 'gudong_id', 'id');
    }

    public function tuike()
    {
        return $this->hasOne(tuikeModel::class, 'tuike_id', 'id');
    }

    public function qudai()
    {
        return $this->hasOne(qudaiModel::class, 'qudai_id', 'id');
    }

    public function twostage()
    {
        return $this->hasOne(\app\modules\Admin\models\twostageModel::class, 'twostage_id', 'id');
    }

    public function checkUsername($username)
    {
        if (empty($username)) return false;
        return $this->where('phone', $username)->exists();
    }

    public function checkPassword($username, $password)
    {
        return $this->where(function ($query) use ($username, $password) {
            $query->where('phone', $username);
        })->where('password', md5($password))->exists();
    }

    public function checkSmsCode($mobile, $code)
    {
        return smscodeModel::where(function ($query) use ($mobile, $code) {
            $query->where('mobile', $mobile);
        })->where('code', $code)->exists();
    }

    public function checkStatus($username)
    {
        return $this->where('phone', '=', $username)->where('lock_until', '<', time())->where('status', '=', 1)->exists();
    }

    public function accountLogin($username)
    {
        if ($user = $this->where(function ($query) use ($username) {
            $query->where('phone', $username);
        })->first()) {
            return $this->userLoginSignal($user);
        } else {
            return false;
        }
    }

    public function wxminiLogin($openid)
    {
        if ($user = $this->where('openid', '=', $openid)->first()) {
            return $this->userLoginSignal($user);
        }
        return false;
    }

    private function userLoginSignal($user): array
    {
        $ip = getIp();
        if (empty($user->token)) {
            $token = md5($user->id . $ip . $user->phone . $user->nickname . $user->logined_at . rand(10000, 99999));
        } else {
            $token = $user->token;
        }
        $rows = [
            'token'       => $token,
            'try_times'   => 0,
            'login_times' => intval($user->login_times) + 1,
            'logined_ip'  => $ip,
            'logined_at'  => date('Y-m-d H:i:s'),
            'lock_until'  => 0,
        ];
        $this->where('id', '=', $user->id)->update($rows);
        return [
            'userInfo' => [
                'token'    => $token,
                'phone'    => $user->phone,
                'nickname' => $user->nickname,
                'avatar'   => $user->avatar,
            ]
        ];
    }

    /**
     * @name 变更会员余额
     * @param float $money 变更金额
     * @param int|object $user 会员对象或会员ID
     * @param string $event 变更类型
     * @param int $event_id 变更ID
     * @param string $remark 备注
     * @return boolean
     */
    public static function money($money, $user, $event = '', $event_id = 0, $remark = '')
    {
        // 判断用户
        if (is_numeric($user)) {
            $user_id = $user;
        } else {
            $user_id = $user->id;
        }
        $user = memberModel::where('id', $user_id)->lockForUpdate()->first();
        if (!$user) {
            throw new Exception('未找到用户');
        }
        // 判断金额
        if ($money == 0) {
            throw new Exception('请输入正确的金额');
        }

        $before = $user->money;
        $after  = $user->money + $money;
        // 只有后台扣除用户余额和佣金退回和佣金发放，余额才可以是负值
        $allowArray = ['admin_deduct', 'commission_back', 'admin_recharge', 'commission_income', 'order_refund', 'refund', 'wallet_refund',
            'jichafenhong', 'pingjifenhong', 'gudongfenhong', 'qudaifenhong', 'tuikefenhong', 'transfer_in',
            'jichafenhong_back', 'pingjifenhong_back', 'gudongfenhong_back', 'qudaifenhong_back', 'tuikefenhong_back', 'renwufenhong_back'];
        if ($after < 0 && !in_array($event, $allowArray)) {
            throw new Exception('可用余额不足:'.$event);
        }
        try {
            // 更新会员余额信息
            $user->money = DB::raw('money + ' . $money);
            $user->save();
            membermoneylogModel::insert([
                'member_id' => $user->id,
                'event'     => $event,
                'event_id'  => $event_id,
                'before'    => $before,
                'money'     => $money,
                'after'     => $after,
                'remark'    => $remark,
                'created_at' => timestamp(),
            ]);
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }

        // 写入shopro日志
        return true;
    }

    /**
     * @name 冻结会员积分
     * @param int $score 冻结积分数量
     * @param int|object $user 会员对象或会员ID
     * @param int $orderid 订单ID
     * @return boolean
     */
    public static function freezeScore($score, $user, $orderid)
    {
        $score = intval($score);
        // 判断用户
        if (is_numeric($user)) {
            $user_id = $user;
        } else {
            $user_id = $user->id;
        }
        $user = memberModel::where('id', $user_id)->lockForUpdate()->first();
        if (!$user) {
            throw new Exception('未找到用户');
        }
        // 判断积分
        if ($score === 0) {
            throw new Exception('积分数量有误');
        }
        if ($user->score < $score) {
            throw new Exception('积分不足');
        }
        try {
            // 更新会员余额信息
            $before = $user->score;
            $user->score = Db::raw('score - ' . $score);
            $user->score_frozen = Db::raw('score_frozen + ' . $score);
            $user->save();
//            memberscorelogModel::insert([
//                'member_id' => $user->id,
//                'event'     => 'freeze',
//                'event_id'  => $orderid,
//                'before'    => $before,
//                'score'     => -1 * $score,
//                'after'     => $before - $score,
//                'remark'    => '积分订单预支付冻结用户积分',
//                'created_at' => timestamp(),
//            ]);
        } catch (\Exception $e) {
            throw new Exception('用户积分处理异常');
        }
        return true;
    }

    /**
     * @name 解冻会员积分
     * @param int $score 解冻积分数量
     * @param int|object $user 会员对象或会员ID
     * @param int $orderid 订单ID
     * @return boolean
     */
    public static function unfreezeScore($score, $user, $orderid)
    {
        $score = intval($score);
        // 判断用户
        if (is_numeric($user)) {
            $user_id = $user;
        } else {
            $user_id = $user->id;
        }
        $user = memberModel::where('id', $user_id)->lockForUpdate()->first();
        if (!$user) {
            throw new Exception('未找到用户');
        }
        // 判断积分
        if ($score === 0) {
            throw new Exception('积分数量有误');
        }
        if ($user->score_frozen < $score) {
            throw new Exception('积分不足');
        }
        try {
            // 更新会员余额信息
            $before = $user->score;
            $user->score_frozen = Db::raw('score_frozen - ' . $score);
            $user->score = Db::raw('score + ' . $score);
            $user->save();
//            memberscorelogModel::insert([
//                'member_id' => $user->id,
//                'event'     => 'unfreeze',
//                'event_id'  => $orderid,
//                'before'    => $before,
//                'score'     => $score,
//                'after'     => $before + $score,
//                'remark'    => '订单取消恢复用户积分',
//                'created_at' => timestamp(),
//            ]);
        } catch (\Exception $e) {
            throw new Exception('用户积分处理异常');
        }
        return true;
    }

    /**
     * @name 变更会员积分
     * @param int $score 变更积分数量
     * @param int|object $user 会员对象或会员ID
     * @param string $event 变更类型
     * @param int $event_id 变更ID
     * @param string $remark 备注
     * @return boolean
     */
    public static function score($score, $user, $event = '', $event_id = 0, $remark = '')
    {
//        $score = intval($score);
        // 判断用户
        if (is_numeric($user)) {
            $user_id = $user;
        } else {
            $user_id = $user->id;
        }
        $user = memberModel::where('id', $user_id)->lockForUpdate()->first();
        if (!$user) {
            throw new Exception('未找到用户');
        }
        // 判断积分
        if ($score === 0) {
            throw new Exception('请输入正确的积分数量');
        }
        if ($event == 'orderpay') {
            $before = $user->score + abs($score);
            $after  = $user->score;
            if ($user->score_frozen < abs($score)) {
                $cscore = abs($score)-$user->score_frozen;
                //throw new Exception('积分不足');
                $user->score_frozen = 0;
                $user->score = $user->score - $cscore;
            }else{
                $user->score_frozen = Db::raw('score_frozen - ' . abs($score));
            }
        } else {
            $before = $user->score;
            $after  = $user->score + $score;
            // 只有后台扣除用户余额和佣金退回，余额才可以是负值
            if ($after < 0 && !in_array($event, ['admin_deduct', 'admin_recharge', 'sign', 'signin', 'orderaward', 'orderaward_back', 'share'])) {
                throw new Exception('可用积分不足');
            }
            $user->score = Db::raw('score + ' . $score);
        }
        try {
            // 更新会员余额信息
            $user->save();
            if ($score !== 0) {
                memberscorelogModel::insert([
                    'member_id' => $user->id,
                    'event'     => $event,
                    'event_id'  => $event_id,
                    'score'     => $score,
                    'before'    => $before,
                    'after'     => $after,
                    'remark'    => $remark,
                    'created_at' => timestamp(),
                ]);
            }
        } catch (\Exception $e) {
            throw new Exception('您提交的数据不正确' . $e->getMessage());
        }
        return true;
    }


    /**
     * @name 变更金币变更
     * @param int $score 变更积分数量
     * @param int|object $user 会员对象或会员ID
     * @param string $event 变更类型
     * @param int $event_id 变更ID
     * @param string $remark 备注
     * @return boolean
     */
    public static function people($score, $user, $event = '', $event_id = 0, $remark = '',$type=1)
    {
//        $score = $score;
        // 判断用户
        if (is_numeric($user)) {
            $user_id = $user;
        } else {
            $user_id = $user->id;
        }
        $user = memberModel::where('id', $user_id)->first();
        if (!$user) {
            throw new Exception('未找到用户');
        }
        // 判断积分
        if ($score === 0) {
            throw new Exception('请输入正确的积分数量');
        }
        if ($event == 'orderpay') {
            $before = $user->people +$score;
            $after  = $user->people;
            if ($user->people_frozen <$score) {
                $cscore =$score-$user->people_frozen;
                //throw new Exception('积分不足');
                $user->people = 0;
                $user->people = $user->people - $cscore;
            }else{
                $user->people_frozen = Db::raw('people_frozen - ' .$score);
            }

        } else {
            $before = $user->people;
            $after  = $user->people + $score;
            // 只有后台扣除用户余额和佣金退回，余额才可以是负值
            if ($after < 0 && !in_array($event, ['admin_deduct', 'admin_recharge', 'sign', 'signin', 'orderaward', 'orderaward_back', 'share'])) {
                throw new Exception('可用金币不足');
            }
            $user->people = Db::raw('people + ' . $score);
        }
        try {
            // 更新会员余额信息
            $user->save();
            if($type == 1){
                if ($score !== 0) {
                    memberpeoplelogModel::insert([
                        'member_id' => $user->id,
                        'event'     => $event,
                        'event_id'  => $event_id,
                        'people'    => $score,
                        'before'    => $before,
                        'after'     => $after,
                        'remark'    => $remark,
                        'created_at' => timestamp(),
                    ]);
                }
            }

        } catch (\Exception $e) {
            throw new Exception('您提交的数据不正确' . $e->getMessage());
        }
        return true;
    }

    /**
     * @param float|string|int $team_consume 变更团队业绩数量
     * @param int|object $user 会员对象或会员ID
     * @param string $event 变更类型
     * @param int $event_id 变更ID
     * @param string $remark 备注
     * @param string $oper_type 操作人
     * @param int $oper_id 操作人ID
     * @return boolean
     * @throws Exception
     */
    public static function teamConsume($team_consume, $user, $event = '', $event_id = 0, $remark = '', $oper_type = 'admin', $oper_id = 0)
    {
        if(!in_array($event, ['adjustment'])){
            throw new Exception('事件出错');
        }
        $team_consume = bcadd($team_consume, 0, 2);
        // 判断用户
        if (is_numeric($user)) {
            $user = self::find($user);
        }

        if (!$user) {
            throw new Exception('未找到用户');
        }
        $issub = bccomp($team_consume, 0, 2);
        // 判断团队业绩
        if ($issub === 0) {
            throw new Exception('请输入正确的团队业绩数量');
        }

        // 前置判断 团队业绩不可以是负值
        if (($issub === -1) && (bccomp($user->team_consume, abs($team_consume), 2) === -1)) {
            throw new Exception('现有团队业绩不足');
        }

        try {
            // 更新会员团队业绩信息
            $lastMember = memberModel::query()->where('id', $user->id)->lockForUpdate()->first();
            $before = $lastMember->team_consume;
            if($issub === -1){
                $after  = bcsub($lastMember->team_consume, abs($team_consume), 2);
            }else{
                $after  = bcadd($lastMember->team_consume, abs($team_consume), 2);
            }
            $user->team_consume = $after;
            $user->save();
            if ($issub !== 0) {
                \app\modules\Admin\models\memberteamconsumeadjustlogModel::addLogs([
                    'member_id'  =>  $user->id,
                    'event'      =>  $event,
                    'event_id'   =>  $event_id,
                    'before'     =>  $before,
                    'adjust'     =>  $team_consume,
                    'after'      =>  $after,
                    'remark'     =>  $remark,
                    'oper_type'  =>  $oper_type,
                    'oper_id'    =>  $oper_id,
                ]);
            }
        } catch (\Exception $e) {
            throw new Exception('您提交的数据不正确');
        }
        return true;
    }

}

